package com.sunjee.gateway.config;

import cn.dev33.satoken.exception.DisableLoginException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.json.JSONUtil;
import com.framework.common.api.CommonResult;
import com.framework.common.api.ResultCode;
import com.framework.common.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author lihanbo
 */
@Configuration
@Order(-1)
@Slf4j
public class GlobalErrorExceptionHandler implements ErrorWebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        if (response.isCommitted()) {
            return Mono.error(ex);
        }
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        if (ex instanceof ResponseStatusException) {
            response.setStatusCode(((ResponseStatusException) ex).getStatus());
        }
        log.error("全局异常捕获", ex);
        return response.writeWith(Mono.fromSupplier(() -> {
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            CommonResult<?> commonResult = null;
            if (ex instanceof NotLoginException) {
                // 如果是未登录异常
                NotLoginException ee = (NotLoginException) ex;
                commonResult = CommonResult.unauthorized(ee.getMessage());
            } else if (ex instanceof NotRoleException) {
                // 如果是角色异常
                NotRoleException ee = (NotRoleException) ex;
                commonResult = CommonResult.failed("无此角色：" + ee.getRole());
            } else if (ex instanceof NotPermissionException) {
                // 如果是权限异常
                NotPermissionException ee = (NotPermissionException) ex;
                commonResult = CommonResult.failed("无此权限：" + ee.getCode());
            } else if (ex instanceof DisableLoginException) {
                // 如果是被封禁异常
                DisableLoginException ee = (DisableLoginException) ex;
                commonResult = CommonResult.failed("账号被封禁：" + ee.getDisableTime() + "秒后解封");
            } else if (ex instanceof ApiException) {
                ApiException ee = (ApiException) ex;
                if (ee.getErrorCode() != null) {
                    commonResult = CommonResult.failed(ee.getErrorCode(), ee.getMessage());
                } else {
                    commonResult = CommonResult.failed(ee.getMessage());
                }
            } else {
                // 普通异常, 输出：500 + 异常信息
                commonResult = CommonResult.failed(ex.getMessage());
            }
            return dataBufferFactory.wrap(JSONUtil.toJsonStr(commonResult).getBytes());
        }));
    }
}
